////////////////////////////////////////////////////////////////////////////////
// Copyright 2010 Michael Schmalle - Teoti Graphix, LLC
// 
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// 
// http://www.apache.org/licenses/LICENSE-2.0 
// 
// Unless required by applicable law or agreed to in writing, software 
// distributed under the License is distributed on an "AS IS" BASIS, 
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and 
// limitations under the License
// 
// Author: Michael Schmalle, Principal Architect
// mschmalle at teotigraphix dot com
////////////////////////////////////////////////////////////////////////////////

package org.teotigraphix.swizplugin.registry
{

import flash.events.IEventDispatcher;

import org.teotigraphix.swizplugin.api.IPlugin;
import org.teotigraphix.swizplugin.bundles.IBundle;

/**
 * The <strong>IExtensionRegistry</strong> manages <code>IContributor</code>,
 * <code>IExtensionPoint</code>, <code>IExtension</code> and 
 * <code>IExtensionDescriptor</code> instances.
 * 
 * <p>The extension registry is used to register extension points and plugin
 * extensions against those points.</p>
 * 
 * <p>Each <code>IExtension</code> is capable of holding 
 * <code>IExtensionDescriptor</code> and each <code>IExtensionDescriptor</code> 
 * can hold more <code>IExtensionDescriptor</code> as children.</p>
 * 
 * <p>The <code>initializePlugin()</code> method is a specail method that can 
 * automatically parse <code>IPlugin</code> instances. If an application does
 * not use this method to initialize the registry, the add methods can be used
 * externally to populate the extension registry in the same way.</p>
 * 
 * @author Michael Schmalle
 * @copyright Teoti Graphix, LLC
 * @productversion 1.0
 * 
 * @see #addContributor()
 * @see #addExtensionPoint()
 * @see #addExtension()
 * @see #addExtensionDescriptor()
 */
public interface IExtensionRegistry extends IEventDispatcher
{
	//--------------------------------------------------------------------------
	//
	//  Methods
	//
	//--------------------------------------------------------------------------
	
	/**
	 * Initializes a <code>IBundle</code>'s extension point and extension
	 * instances.
	 */
	function addBundle(bundle:IBundle):void;
	
	/**
	 * Adds an <code>IContributor</code> contributor to the registry.
	 * 
	 * <p>This method usually will take a <code>RegistryContributor</code> 
	 * instance that owns an <code>IPlugin</code> declaration.</p>
	 * 
	 * @param contributor An <code>IContributor</code> instance.
	 */
	function addContributor(contributor:IContributor):void;
	
	/**
	 * Adds an extension point to the registry.
	 * 
	 * @param contributor The <code>IContributor</code> that owns the extension
	 * point.
	 * @param extensionPointID A unique String identifier usually in reverse 
	 * domain format. (<code>com.acme.splash</code>)
	 * @param extensionPointName A String indicating the display name of the 
	 * extension point. This name can be <code>null</code>. This parameter refers
	 * to the <code>IPluginExtensionPoint#name</code> property when an extension
	 * point is added by the parser.
	 * @return The <code>IExtensionPoint</code> instance created and added to
	 * the registry.
	 */
	function addExtensionPoint(contributor:IContributor,
							   extensionPointID:String,
							   extensionPointName:String):IExtensionPoint;
	
	/**
	 * Adds an extension to the registry.
	 * 
	 * @param contributor The <code>IContributor</code> that owns the extension.
	 * @param extensionID A unique extension id. This id can be 
	 * <code>null</code>.
	 * @param extensionPointID A unique String identifier usually in reverse 
	 * domain format. (<code>com.acme.splash</code>)
	 * @param extensionName A string indicating the display name of the 
	 * extension. This name can be <code>null</code>. This parameter refers
	 * to the <code>IPluginExtension#name</code> property when an extension
	 * is added by the parser.
	 */
	function addExtension(contributor:IContributor,
						  extensionID:String,	
						  extensionPointID:String,
						  extensionName:String):IExtension;
	/**
	 * Adds an extension descriptor to the registry.
	 * 
	 * @param contributor The <code>IContributor</code> that owns the extension
	 * descriptor.
	 * @param parentID The registryID of the parent extension or 
	 * extension descriptor.
	 * @param name A String name of the descriptor, this is like a tag name.
	 * This name must be set in either the MXML declaration of the descriptor
	 * or in the <code>PluginOptions</code> subclass.
	 * @param properties The decorated value object of the descriptor. This will
	 * either be an XML node that is transformed into an <code>Object</code> or
	 * a <code>PluginOptions</code> instance declared in MXML.
	 */
	function addExtensionDescriptor(contributor:IContributor,
									parentID:int,
									name:String,
									properties:Object):IExtensionDescriptor
	
	/**
	 * Returns a registry contributor for the identifier.
	 * 
	 * @param An int identifier that can be found in the registries 
	 * contributors.
	 * @return An <code>IContributor</code> if found, <code>null</code> if not.
	 */
	function getContributor(id:int):IContributor;
	
	/**
	 * Returns an <code>IExtensionPoint</code> by full extension point
	 * uid or namespace and point name.
	 * 
	 * @param nameSpace A String either namespace or full extension point uid.
	 * @param pointName An optional String pointName if only the nameSpace is
	 * provided.
	 * @return An <code>IExentionPoint</code>, <code>null</code> if not found.
	 */
	function getExtensionPoint(nameSpace:String, 
							   pointName:String = null):IExtensionPoint;
	
	/**
	 * Returns all <code>IExtensionPoint</code> registry entries.
	 * 
	 * @return An Array of <code>IExtensionPoint</code>.
	 */
	function getExtensionPoints():Array; // of IExtensionPoint
	
	/**
	 * Returns an <code>IExtension</code> for the extensionID.
	 * 
	 * <p>If the extensionPointID is not null, only that extension point
	 * will be searched.
	 * 
	 * @param extensionID The String identifier for the exension.
	 * @param extensionPointID The String identifier for the extension's 
	 * extension point.
	 * 
	 * @return An <code>IExtension</code>, <code>null</code> if not found.
	 */
	function getExtension(extensionID:String, 
						  extensionPointID:String = null):IExtension;
	
	/**
	 * Returns an <code>IExtension</code> found for the plugin, extension point
	 * name and extension String identifier.
	 * 
	 * @param extensionID The String identifier for the exension.
	 * @param extensionPointID The String identifier for the extension's 
	 * extension point.
	 * 
	 * @return An <code>IExtension</code>, <code>null</code> if not found.
	 */
	function getExtensionFor(pluginID:String,
							 extensionPointName:String,
							 extensionID:String):IExtension;
	
	/**
	 * Returns an Array of <code>IExtension</code> instances for either
	 * the whole contributor or if the <code>extensionPointName</code>
	 * is not null, the contributor's extension point.
	 * 
	 * @param contributor The <code>IContributor</code> owning the extensions.
	 * @param extensionPointID The String identifier for the extension's 
	 * extension point, can be null, if so returns all <code>IExtension</code>
	 * instances for the contributor.
	 * 
	 * @return An Array of <code>IExtension</code> or empty Array.
	 */
	function getExtensionsForContributor(contributor:IContributor,
										 extensionPointName:String = null):Array; // of IExtension
	
	/**
	 * Returns an Array of all <code>IExtension</code> entries found for the
	 * extensionPointID.
	 * 
	 * @param extensionPointID A String identifier for the extension point.
	 * 
	 * @return An Array of <code>IExtension</code>.
	 */
	function getExtensions(extensionPointID:String):Array; // of IExtension
	
	/**
	 * Returns an Array of all <code>IExtensionDescriptor</code> entries found 
	 * for the <code>IExtension</code>.
	 * 
	 * @param extension An <code>IExtension</code> to return it's descriptors.
	 * @param extensionPointID An optional String identifier for the extension point.
	 * 
	 * @return An Array of <code>IExtensionDescriptor</code>, never <code>null</code>.
	 */
	function getExtensionDescriptors(extension:IExtension,
									 extensionPointID:String = null):Array;
	
	/**
	 * Returns an Array of all <code>IExtensionDescriptor</code> entries found 
	 * for the extensionPointID.
	 * 
	 * @param extensionPointID A String identifier for the extension point.
	 * 
	 * @return An Array of <code>IExtensionDescriptor</code>.
	 */
	function getExtensionDescriptorsFor(extensionPointID:String):Array;
	
	/**
	 * Returns an <code>IExtensionDescriptor</code> entry found 
	 * for the descriptorID and in the extensionPointID.
	 * 
	 * @param descriptorID A String identifier for the descriptor.
	 * @param extensionPointID A String identifier for the extension point.
	 * 
	 * @return An <code>IExtensionDescriptor</code>.
	 */
	function getExtensionDescriptorByID(descriptorID:String, 
										extensionPointID:String):IExtensionDescriptor;
}
}